﻿using AutoMapper;
using MediatR;
using Production.CommonLib.Models;
using Production.DomainLib.AggregatesModel.StandardBomAggregate;
using Swimj.CommonLib.Base;

namespace Production.ApplicationLib.Command;

public class UpdateStandardBomCommand : StandardBomEditRequestDto, IRequest<Result<StandardBomInfoResponseDto>>
{
    public int Id { get; set; }
}

public class
    UpdateStandardBomCommandHandler : IRequestHandler<UpdateStandardBomCommand, Result<StandardBomInfoResponseDto>>
{
    private readonly IStandardBomRepository _standardBomRepository;
    private readonly IMapper _mapper;

    public UpdateStandardBomCommandHandler(IStandardBomRepository standardBomRepository,
        IMapper mapper)
    {
        _standardBomRepository = standardBomRepository;
        _mapper = mapper;
    }

    public async Task<Result<StandardBomInfoResponseDto>> Handle(UpdateStandardBomCommand request,
        CancellationToken cancellationToken)
    {
        var standardBom = await _standardBomRepository.Get(request.Id);
        if (standardBom != null)
        {
            standardBom.Update(request.Name, request.Version,
                request.Contract, request.Material.Id, request.Material.Code, request.Material.Name,
                request.Quality, request.Description);

            var delItems = standardBom.Items!.Where(i => request.Items!.All(m => m.Id != i.Id)).ToList();

            foreach (var item in delItems)
            {
                standardBom.RemoveItem(item);
            }
            
            foreach (var item in request.Items!)
            {
                if (item.Id > 0)
                {
                    standardBom.UpdateItem(item.Id, item.MaterialId, item.MaterialCode, item.MaterialName,
                        item.Quality,
                        item.LossRate);
                }
                else
                {
                    standardBom.AddItem(item.MaterialId, item.MaterialCode, item.MaterialName, item.Quality,
                        item.LossRate);
                }
            }
        }

        await _standardBomRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        return await Result<StandardBomInfoResponseDto>.SuccessAsync(
            _mapper.Map<StandardBomInfoResponseDto>(standardBom));
    }
}